#pragma once

#include "Ray.h"
#include "Color4.h"

class CScene;
class CRenderer
{
public:
	enum SAMPLING_MODE
	{
		SM_BASIC = 0,
		SM_JITTERED,
		SM_ADAPTIVE
	};

	CRenderer(void);
	virtual ~CRenderer(void);

	void Init();
	void Render(const CScene* pScene);

	SAMPLING_MODE GetSamplingMode() const { return m_samplingMode; }
	void SetSamplingMode(SAMPLING_MODE newMode) { m_samplingMode = newMode; }

	unsigned int GetMaxReflection() const { return m_uiMaxReflection; }
	void SetMaxReflection(unsigned int uiMaxReflection) { m_uiMaxReflection = uiMaxReflection; }

	bool GetReflectionEnabled() const { return m_bReflectionEnabled; }
	void SetReflectionEnabled(bool bValue) { m_bReflectionEnabled = bValue; }

	bool GetRefractionEnabled() const { return m_bRefractionEnabled; }
	void SetRefractionEnabled(bool bValue) { m_bRefractionEnabled = bValue; }

	const unsigned char* GetPixels() const { return m_pPixels; }

	const CColor4& GetBGColor() const { return m_backgroundColor; }
	void SetBGColor(const CColor4 color) { m_backgroundColor = color; }

	void SetMotionBlurEnabled(bool bValue) { m_bMotionBlurEnabled = bValue; }
	void SetDepthOfFieldEnabled(bool bValue) { m_bDepthOfFieldEnabled = bValue; }
	void SetMotionBlurValue(DATA_TYPE fValue) { m_fMotionBlurValue = fValue; }
	void SetDepthOfFieldValue(DATA_TYPE fValue) { m_fDepthOfFieldValue = fValue; }
	void SetKDTreeEnabled(bool bValue) { m_bUseKDTree = bValue; }

	void DoRender();

	static void SetGlobalTime(DATA_TYPE fTime) { ms_fGlobalTime = fTime; }
	static DATA_TYPE GetGlobalTime() { return ms_fGlobalTime; }

protected:
	CColor4 GetPixelColor(DATA_TYPE pixelX, DATA_TYPE pixelY);
	CColor4 GetColor(DATA_TYPE x, DATA_TYPE y);
	CColor4 GetColorAdaptiveSS(DATA_TYPE x, DATA_TYPE y, DATA_TYPE size);
	CColor4 GetColor(CRay ray, unsigned int uiReflections, DATA_TYPE fPrevRefraction);

	unsigned char* m_pPixels;
	const CScene* m_pScene;

	SAMPLING_MODE m_samplingMode;
	unsigned int m_uiMaxReflection;
	bool m_bReflectionEnabled;
	bool m_bRefractionEnabled;
	CColor4 m_backgroundColor;

	bool m_bMotionBlurEnabled;
	bool m_bDepthOfFieldEnabled;
	DATA_TYPE m_fMotionBlurValue;
	DATA_TYPE m_fDepthOfFieldValue;

	int m_iNextRenderLine;

	static DATA_TYPE ms_fGlobalTime;

	bool m_bUseKDTree;
};

